;; -*-mode:scheme; coding:utf-8-*-

(define load-data-list
  (lambda (data-list)
    (let ((item (read)))
      (if (not (eof-object? item))
	  (load-data-list (cons item data-list))
	  data-list)
      )
    )
  )

(define data-list (load-data-list '()))

(define get-name car)
(define get-start-time caddr)
(define get-end-time cadddr)

(define get-used-time
  (lambda (item)
    (- (get-end-time item)
       (get-start-time item))))

(define sort-data-list
  (lambda (data-list)
    (let ((sorted-data-list '()))
      (for-each (lambda (item)
		  (let ((item-list (assoc (get-name item) sorted-data-list)))
		    (if item-list
			(set-cdr! item-list (cons (get-used-time item) (cdr item-list)))
			(set! sorted-data-list (cons
						(list (get-name item) (get-used-time item))
						sorted-data-list)))))
		data-list)
      sorted-data-list)))

(define sorted-data-list (sort-data-list data-list))

(define get-sorted-name car)
(define get-sorted-time cdr)

(define (average num-list)
  (exact->inexact (/ (apply + num-list) (length num-list))))

(define (show-status item)
  (display "avg: ")
  (display (average (get-sorted-time item)))
  (display "\t")
  (display "sum: ")
  (display (apply + (get-sorted-time item))))

(define print-sorted-data-list
  (lambda (sorted-data-list)
    (for-each (lambda (item)
		(display (get-sorted-name item))
		(display " ")
		(show-status item)
		;(display " ")
		;(display (get-sorted-time item))
		(newline))
	      sorted-data-list)))

(define (sort-insert result lst item cmp)
  (if (not (null? lst))
      (if (cmp item (car lst))
	  (append result (cons item (cons (car lst) (cdr lst))))
	  (sort-insert (append result (list (car lst)))
		       (cdr lst)
		       item
		       cmp))
      (append result (list item))))

(define (item-less-by-avg item-a item-b)
  (let ((avg-a (average (get-sorted-time item-a)))
	(avg-b (average (get-sorted-time item-b))))
    (< avg-a avg-b)))

(define (item-less-by-sum item-a item-b)
  (let ((sum-a (apply + (get-sorted-time item-a)))
	(sum-b (apply + (get-sorted-time item-b))))
    (< sum-a sum-b)))

(define sort-by
  (lambda (result sorted-data-list cmp)
    (if (null? sorted-data-list)
	result
	(sort-by (sort-insert '() result (car sorted-data-list) cmp)
		 (cdr sorted-data-list)
		 cmp))))

(display "sort-by-avg\n")
(print-sorted-data-list (sort-by '() sorted-data-list item-less-by-avg))

(display "sort-by-sum\n")
(print-sorted-data-list (sort-by '() sorted-data-list item-less-by-sum))

;(display "all data\n")
;(print-sorted-data-list sorted-data-list)
